var inited = false;
// var shell = window.shell;
var scripts = [];
const noPrivileges = [
    "exec",
    "existDir",
    "existFile",
    "getPath",
    "readDir",
    "readFile",
    "removeFile",
];
const scriptShell = {};

function init() {
    if (!shell) {
        console.log("shell not ready");
        setTimeout(init, 1000);
    } else {
        shell.mkdirs("script");
        scripts = load();
        Object.keys(shell).forEach(function(k) {
            if (noPrivileges.indexOf(k) < 0) {
                scriptShell[k] = function() {
					try {
						return shell[k].apply(shell, arguments);
					} catch (error) {
						console.log(error);
					}
                };
            }
        });
    }
}
setTimeout(init);

function load() {
    var data = shell.readFile("scripts.json");
    data = JSON.parse(data);
    return data.filter(read);
}

function applog(title) {
    return {
        log: function() {
            console.log.apply(console, [`[${title}]:`].concat(Array.from(arguments)));
        }
    };
}

function warpParam(params) {
    var data = {};
    (params || []).forEach(function(x) {
        data[x.key] = x.value;
    });
    return data;
}

function read(x) {
    try {
        var text = shell.readFile("script/" + x.id);
        var m = { exports: {} };
        new Function("exports", "module", "console", "window", text)(m.exports, m, applog(x.title), null);
        x.package = m.exports.package;
        var params = [];
        if (m.exports.params) {
            params = m.exports.params;
            if (x.params) {
                var pm = {};
                for (let p of x.params) {
                    pm[p.key] = p.value;
                }
                for (let p of params) {
                    p.value = pm[p.key] || p.value;
                }
            }
        }
        x.params = params;
        x.script = m.exports.script(scriptShell, warpParam(x.params));
        return true;
    } catch (error) {
        console.log(error);
    }
    return false;
}

function get(id) {
    for (let i = 0; i < scripts.length; i++) {
        var x = scripts[i];
        if (x.id == id) {
            return x;
        }
    }
    return { script: { recv: function() {}, run: function() {} } };
}

shell.find = function(data, fn) {
    if (typeof data == "function") {
        fn = data;
        data = shell.getView();
    }
    if (!data) return;
    if (data instanceof Array) {
        var aim;
        for (var key = 0; !aim && key < data.length; key++) {
            aim = shell.find(data[key], fn);
        }
        return aim;
    }
    if (fn(data)) {
        return data;
    }
    return shell.find(data.children, fn);
};

shell.findall = function(data, fn, arr) {
    if (typeof data == "function") {
        arr = fn;
        fn = data;
        data = shell.getView();
    }
    arr = arr || [];
    if (!data) return arr;
    if (data instanceof Array) {
        for (var key = 0; key < data.length; key++) {
            shell.findall(data[key], fn, arr);
        }
        return arr;
    }
    if (fn(data)) {
        arr.push(data);
    }
    return shell.findall(data.children, fn, arr);
};

shell.getView = function() {
    var text = shell.getCurrentView();
    var tree;
    if (text) {
        return JSON.parse(text);
    }
    shell.doAction(3);
    shell.doAction(3);
    var text = shell.getCurrentView();
    if (text) {
        return JSON.parse(text);
    }
    console.log("empty");
    return;
};

function checkPackage(x, data) {
    if (x.package == "all") {
        return true;
    }
    if (x.package instanceof Array) {
        for (let i = 0; i < x.package.length; i++) {
            if (x.package[i] == data.packageName) {
                return true;
            }
        }
        return false;
    }
    return data.packageName == x.package;
}

const ignore = [
    "com.android.systemui",
];

function onAccessibilityEvent(data) {
    if (data.type == "TYPE_NOTIFICATION_STATE_CHANGED" && data.packageName == "cn.inu1255.threehands") {
        if (data.text) {
            var text = data.text.replace(/^手替：/, "");
            if (text.startsWith("添加成功")) {
                location.reload();
            } else if (text.startsWith("删除成功")) {
                location.reload();
            } else if (text.startsWith("修改成功")) {
                location.reload();
            } else {
                var m = /\d+$/.exec(data.text);
                if (m) {
                    var id = m[0];
                    console.log(scripts[id]);
                    if (text.startsWith("执行脚本")) {
                        setTimeout(function() { get(id).script.run(); });
                    }
                }
            }
        }
    }
    var handled = false;
    scripts.forEach(function(x) {
        if (!x.enabled) return false;
        if (checkPackage(x, data)) {
            if (x.script[data.type]) {
                setTimeout(function() { x.script[data.type](data); });
                handled = true;
            }
        }
    });
    if (!handled && ignore.indexOf(data.packageName) < 0) {
        console.log("未处理的消息", data);
    }
}